package com.siyu.model.dispatch.model.optimal.singlersvr;

import com.alibaba.fastjson.JSONObject;
import com.siyu.model.dispatch.algorithm.MinimumDischargeSingleReservoir;
import com.siyu.model.dispatch.algorithm.MuskingenMethod;
import com.siyu.model.dispatch.dto.DispatchDto;
import com.siyu.model.dispatch.io.*;
import com.siyu.model.dispatch.model.interfaces.Model;
import com.siyu.model.dispatch.utils.CommonUtils;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class SingleRsvr implements Model {
    /*
     * 实例字段
     */
    protected Logger logger = LogManager.getLogger(this.getClass());
    private final String folderPath;

    /**
     * 有初始化参数文件路径的构造器
     *
     * @param path
     */
    public SingleRsvr(String path) {
        this.folderPath = path;
    }

    /**
     * 模型初始化
     *
     * @return 模型初始化参数对象(BainiheInput)
     */
    public FloodDispatchInput initModel(DispatchDto dispatchDto) throws Exception {
        FloodDispatchInput input = new FloodDispatchInput();
        SingleReservoir singleReservoir = new SingleReservoir(folderPath);

        /*
         * SingleDamInput 初始化过程
         */
        // todo 读取第1座水库的数据，现在是从txt，后面改为数据库读取
        SingleDamInput SingleDamInput1 = singleReservoir.getSingleDamInput(dispatchDto);
       /* if (SingleDamInput1 == null) {
            return null;
        }*/

        /*
         * 将单个水库输入信息（SingleDamInput、SingleSluiceInput） 存入 总输入类 input（FloodDispatchInput）
         * List 中 3 个水库数据依次顺序为 SingleDamInput1、SingleDamInput2、SingleDamInput3
         */
        input.getDamList().add(SingleDamInput1);

        return input;
    }

    /**
     * 模型计算
     *
     * @param input 模型初始化参数对象(BainiheInput)
     * @return 模型计算结果对象(BainiheResult)
     * @throws IOException
     */
    public FloodDispatchOutput calculate(FloodDispatchInput input) throws Exception {
        FloodDispatchOutput output = new FloodDispatchOutput();

        /*
         * 向输出类中设置预定格式的 JSON 对象
         */
        List<JSONObject> dataList = new ArrayList<>();
        output.setJsonObject(CommonUtils.createJSONObject(dataList));

        // 马斯京根河道演算
        MuskingenMethod oneChannel = new MuskingenMethod();

        // 三坑水库、福源水库和芙蓉嶂 三座水库分别编号3、2、1，计算的时候从下往上算：1,2,3这个顺序
        SingleDamInput singleDamInput1 = input.getDamList().get(0);
        MinimumDischargeSingleReservoir damRes1 = new MinimumDischargeSingleReservoir(singleDamInput1,
                folderPath, "1", oneChannel);
        damRes1.calculate();
        SingleDamOutput singleDamOutput1 = damRes1.getSingleDamOutput();  // 获取单水库结果
        output.getDamList().add(singleDamOutput1);
        dataList.add(CommonUtils.addJSONObject(singleDamInput1, singleDamOutput1));

        int size = output.getDamList().size();
        int gradeSum = 0;
        for (int i = 0; i < size; i++) {
            gradeSum += output.getDamList().get(i).getGrade();
        }
        output.setGrade(gradeSum * 1.0 / size);

        // 马斯京根河道演算
        double[] tempQ1 = damRes1.getTempQ();

        double[] tempChuKouQ1 = new double[damRes1.getOptimalLine_Qrelease()[0].length];

        double[] Qrelease0 = damRes1.getOptimalLine_Qrelease()[0];  // 各时段下泄流量
        int length = Qrelease0.length;


        // 输出马斯京根演算后的鸦岗流量
        List<Double> tempQ = new ArrayList<>();
        for (int j = 0; j < tempQ1.length; j++) {
            tempQ.add(tempQ1[j]  + tempChuKouQ1[j]);
        }
        ChukouResult Chukou = new ChukouResult();
        Chukou.setQ(tempQ);
        output.setChukou(Chukou);

        // 输出到文档，后面可以不要
//        String path = folderPath + File.separator + "ChukouFlowProcessObtainedByMuskingenMethod (MinimumDischarge).txt";
//        StringBuilder oneLine = new StringBuilder();
//        ArrayList<String> list = new ArrayList<>();
//        DecimalFormat myDF = new DecimalFormat("0");
//
//        oneLine.append("tempQ1[j] + tempQ2[j] + tempQ3[j] + tempChuKouQ1[j]: \n");
//        for (int j = 0; j < length; j++) {
//            oneLine.append(myDF.format(tempQ.get(j))).append("\t");
//        }
//        list.add(oneLine.append("\n").toString());
//
//        File file = new File(path);
//        FileUtils.writeLines(file, "UTF-8", list);

        //计算总的调度建议
        String suggestion =
                damRes1.getSingleDamOutput().getSuggestion() + "\n" ;

        output.setCollectSuggestion(suggestion);

        // TODO：这个是调度建议
        CommonUtils.createSchedulingSuggestions2Txt(output, folderPath, "白坭河");

        logger.info("计算结束");

        return output;
    }
}
